package sojo.com.inverter.kafka;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
import sojo.com.inverter.enums.TopicEnum;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * @author cheng_hu
 * @description:
 * @date 2023-02-23 19:12:27
 */
@Slf4j
@Component
public class SendMessageKafka {

    @Autowired
    private  KafkaTemplate<String, String> kafkaTemplate;

    public <U> void sendMessage(Class<U> clazz, U cla) {

        String mqMsg = JSONUtil.toJsonStr(cla);
        String sn = "";
        Map<String, String> data = usersBlankNum(clazz, cla);
        try {
            String className = clazz.getSimpleName();
            String topic = TopicEnum.getTopic(className);
            sn = data.get(TopicEnum.getDeviceIdName(className));
            String finalSn = sn;
            kafkaTemplate.send(topic, mqMsg).addCallback(success -> log.info("发送kafka消息成功!,sn是{}", finalSn), failure -> log.error("发送消息失败!失败原因是:{}", failure.getMessage()));
        } catch (Exception e) {
            log.error("投递kafka消息失败,失败消息的SN码:{}", sn);
            e.printStackTrace();
        }
    }

    public static <U> Map<String, String> usersBlankNum(Class<U> clazz, U cla) {
        //将传过来的对象进行赋值处理，
        //此时u可用来代表传过来的对象（本示意中是Users）,
        //此时可以用u调用传过来对象的方法
        Map<String, String> abc = new HashMap<>();
        U u = clazz.cast(cla);
        //以下是验证此示意中实体类可被操作了
        //getDeclaredFields()：获得某个类的所有声明的字段，即包括public、private和proteced，但是不包括父类的申明字段。
        //.getClass()是一个对象实例的方法，只有对象实例才有这个方法，具体的类是没有的
        for (Field field : u.getClass().getDeclaredFields()) {
            //允许获取实体类private的参数信息 field.setAccessible(true);
            field.setAccessible(true);
            try {
                abc.put(field.getName(), String.valueOf(field.get(u)));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return abc;
    }
}
